/*
 * CS_REQ_WORLD_BOSS_INFO.cpp
 *
 *  Created on: 2014. 1. 8.
 *      Author: jjaehuny
 */

#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Space.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Stamina.h"
#include "../../NResource/Static.h"

#include "../../macro.h"

#include <sstream>

namespace ProjectZ { namespace NCommand {

static void SendAck_CS_REQ_WORLD_BOSS_INFO(User * pUser, int16_t ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_WORLD_BOSS_INFO);
	pUser->Send(pAck);
}

void Command::CS_REQ_WORLD_BOSS_INFO(User * pUser, ::Network::Packet * pPacket)
{
	/*
	/// 랭킹(프로필, 닉네임, 점수)
	/// 던젼TID, 보스TID, 내랭킹, %, 공격 포인트
	CS_REQ_WORLD_BOSS_INFO		 	0x4000
	{
	}

	SC_REQ_WORLD_BOSS_INFO 			0x4001
	{
		s16 sAck;
		u32 u32dlc_version;		    /// 서버 DB에 dlc버전
		u8 u8open;				    /// 1: 열림 0: 닫힘
		u16 u16dungeon_tid;
		u16 u16boss_tid1;

		s32 s32my_rank;				/// -1: 랭킹없음
		u32 u32my_point;
		u8 u8is_get_reward; 		//0: 안받음, 1: 받음

		u8	u8count
		{
			str str_profile_url;
			str str_nick_name;
			str str_social_id;			/// 카톡아이디
			u32 u32point;
		}
	}
	*/

	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("%s NULL == pWorld", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_NO_SPACE);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("%s pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_NO_SPACE);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("%s pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::EventTimeResource * pEventTimeResource = NResource::Static::Instance().GetEventTime();
	if (NULL == pEventTimeResource)
	{
		DEBUGLOG("%s NULL == pEventTimeResource", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::WorldBoss * pWorldBossResource = NResource::Static::Instance().GetWorldBossResource();
	if (NULL == pWorldBossResource)
	{
		DEBUGLOG("%s NULL == pWorldBossResource", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::DLC * pDLC = NResource::Static::Instance().GetDLCResource();
	if (NULL == pDLC)
	{
		DEBUGLOG("%s NULL == pDLC", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Stamina * pStamina = pUser->GetStamina();
	if (NULL == pStamina)
	{
		DEBUGLOG("%s NULL == pStamina", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_INFO(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 월드보스 스태미너 초기화
	pStamina->InitializeWorldBossDungeonKey();

	uint8_t u8open = 0;
	if (false == pEventTimeResource->IsWorldBossEvent(pUser))
	{
		u8open = 0;
	}
	else
	{
		u8open = 1;
	}

	int Rank = -1;
	{
		::NoSQL::Command::Redis clsRedis;
		clsRedis._eServer = ::NoSQL::Command::BaseInfo::REDIS;
		clsRedis._eAction = ::NoSQL::Command::Redis::ZREVRANK;
		clsRedis._key = "RANK";
		std::stringstream stream;
		stream << pUser->GetUserSeq();
		clsRedis._value = stream.str();

		::NoSQL::Command::Auto clsAuto(::NoSQL::GETCOMMANDPOOL());
		clsAuto->SetRedis(clsRedis);

		::NoSQL::SESSION()->SyncExecute(static_cast<int>(RedisServerType::WORLDBOSS_MASTER), clsAuto);

		if (0 == clsAuto->GetResult())
		{
			DEBUGLOG("ZREVRANK RANK : %d", clsAuto->GetRedis()._outRank);
			Rank = clsAuto->GetRedis()._outRank;
		}
		else
		{
			DEBUGLOG("ZRANK RESULT : %d", clsAuto->GetResult());
		}
	}

	double score = 0;
	{
		::NoSQL::Command::Redis clsRedis;
		clsRedis._eServer = ::NoSQL::Command::BaseInfo::REDIS;
		clsRedis._eAction = ::NoSQL::Command::Redis::ZSCORE;
		clsRedis._key = "RANK";
		std::stringstream stream;
		stream << pUser->GetUserSeq();
		clsRedis._value = stream.str();

		::NoSQL::Command::Auto clsAuto(::NoSQL::GETCOMMANDPOOL());
		clsAuto->SetRedis(clsRedis);

		::NoSQL::SESSION()->SyncExecute(static_cast<int>(RedisServerType::WORLDBOSS_MASTER), clsAuto);

		if (0 == clsAuto->GetResult())
		{
			DEBUGLOG("ZREVRANK RANK : %d", clsAuto->GetRedis()._outRank);
			score = clsAuto->GetRedis()._outScore;
		}
		else
		{

		}
	}

	bool bReward = false;
	if (true == pEventTimeResource->IsWorldBossReward(pUser))
	{
		::NoSQL::Command::Redis clsRedis;
		clsRedis._eServer = ::NoSQL::Command::BaseInfo::REDIS;
		clsRedis._eAction = ::NoSQL::Command::Redis::EXISTS;
		std::stringstream stream;
		stream << pUser->GetUserSeq();
		clsRedis._key = stream.str();

		::NoSQL::Command::Auto clsAuto(::NoSQL::GETCOMMANDPOOL());
		clsAuto->SetRedis(clsRedis);

		::NoSQL::SESSION()->SyncExecute(static_cast<int>(RedisServerType::WORLDBOSS_MASTER), clsAuto);

		if (0 == clsAuto->GetResult())
		{
			DEBUGLOG("ZCARD count : %d", clsAuto->GetRedis()._count);
			bReward = clsAuto->GetRedis()._isExist;
		}
		else
		{
			DEBUGLOG("ZCARD clsAuto->GetResult() : %d", clsAuto->GetResult());
		}
	}
	else
	{

	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ACK_OK);
	* pAck << static_cast<uint32_t>(pDLC->GetVersion(pUser->GetCompany()));
	* pAck << static_cast<uint8_t>(u8open);
	* pAck << static_cast<uint16_t>(pWorldBossResource->GetData().u16dungeon_tid);
	* pAck << static_cast<uint16_t>(pWorldBossResource->GetData().u16boss_tid1);

	if (-1 != Rank)
		Rank += 1;

	* pAck << static_cast<int32_t>(Rank);
	//* pAck << static_cast<uint64_t>(pUser->GetUserInfo().worldboss_point);
	* pAck << static_cast<uint64_t>(score);

	if (true == bReward)
		* pAck << static_cast<uint8_t>(0);
	else
		* pAck << static_cast<uint8_t>(1);

	if (0 == u8open)
		* pAck << static_cast<uint32_t>(0);
	else
	{
		DEBUGLOG("%s REMAIN pEventTimeResource->WorldBossEventRemainMinute(pUser) : %d GID : %d",
				__FUNCTION__, pEventTimeResource->WorldBossEventRemainMinute(pUser), pUser->GetUserSeq());
		* pAck << static_cast<uint32_t>(pEventTimeResource->WorldBossEventRemainMinute(pUser));
	}

	auto rankVector = NLogic::Static::Instance().GETWORLDBOSSRANK()->GetRankVector();

	DEBUGLOG("WORLDBOSS %s rankVector size : %d", __FUNCTION__, rankVector.size());

	* pAck << static_cast<uint8_t>(rankVector.size());

	std::for_each(rankVector.begin(), rankVector.end(), [&](NLogic::WorldBossRank::RankValue & value) {
		* pAck << value._profile_url.c_str();
		* pAck << value._nickname.c_str();
		* pAck << value._socialID.c_str();
		* pAck << static_cast<uint64_t>(value._score);
	} );

	pAck->MakePacket(CMD_SC_REQ_WORLD_BOSS_INFO);
	pUser->Send(pAck);

}

} /*NCommand*/ } /*ProjectZ*/


